package edu.ycu.aladdin.web.service.impl;

import edu.ycu.aladdin.web.common.OauthChannel;
import edu.ycu.aladdin.web.config.oauth.BaiduOauthConfig;
import edu.ycu.aladdin.web.config.oauth.GithubOauthConfig;
import edu.ycu.aladdin.web.dao.OauthDao;
import edu.ycu.aladdin.web.dto.User;
import edu.ycu.aladdin.web.dto.tripartite.BaiduToken;
import edu.ycu.aladdin.web.dto.tripartite.BaiduUserInfo;
import edu.ycu.aladdin.web.dto.tripartite.GithubUserInfo;
import edu.ycu.aladdin.web.exception.OauthException;
import edu.ycu.aladdin.web.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author <a href="mailto:wangruihuano@gmail.com">王瑞环</a>
 * @since 2019-04-04 11:01
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private final RestTemplate restTemplate;

    private final MongoTemplate mongoTemplate;

    private final BaiduOauthConfig baiduOauthConfig;

    @Autowired
    public LoginServiceImpl(RestTemplate restTemplate, MongoTemplate mongoTemplate, BaiduOauthConfig baiduOauthConfig) {
        this.restTemplate = restTemplate;
        this.mongoTemplate = mongoTemplate;
        this.baiduOauthConfig = baiduOauthConfig;
    }

    @Override
    public User login(OauthChannel channel, Object info) {

        switch (channel) {
            case BAI_DU:
                return loginByBaidu((String) info);
            case GITHUB:
                return loginByGithub((String) info);
            default:
        }
        return null;
    }

    /**
     * 百度Oauth授权登录
     *
     * @param code 回调code
     * @return 用户信息
     */
    private User loginByBaidu(String code) {

        try {
            String accessUrl = baiduOauthConfig.getAccess_url(code);
            BaiduToken token = restTemplate.getForObject(accessUrl, BaiduToken.class);
            // TODO token可以缓存,后续更新用户信息

            String accessToken = token.getAccess_token();
            String pullInfoUrl = baiduOauthConfig.getUser_info_url(accessToken);
            BaiduUserInfo userInfo = restTemplate.getForObject(pullInfoUrl, BaiduUserInfo.class);

            Criteria criteria = Criteria.where("baiduUserInfo.userid").is(userInfo.getUserid());
            User user = mongoTemplate.findOne(new Query(criteria), User.class, "user");

            if (user == null) {
                user = new User(userInfo);
                mongoTemplate.insert(user, "user");
            }
            return user;
        } catch (Exception e) {
            throw new OauthException("百度授权异常:" + e.getMessage());
        }

    }


    @Autowired
    GithubOauthConfig githubOauthConfig;

    /**
     * github授权登录获取用户信息
     *
     * @param code
     * @return
     */
    private User loginByGithub(String code) {

        try {

            String access_url = githubOauthConfig.getAccess_url(code);
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(access_url, String.class);
            String accessToken = responseEntity.getBody();

            String user_info_url = githubOauthConfig.getUser_info_url(accessToken);
            GithubUserInfo gitUserInfo = restTemplate.getForObject(user_info_url, GithubUserInfo.class);

            Criteria criteria = Criteria.where("githubUserInfo.id").is(gitUserInfo.getId());

            User user = mongoTemplate.findOne(new Query(criteria), User.class, "user");

            if (user == null) {
                user = new User(gitUserInfo);
                mongoTemplate.insert(user);
            }
            return user;

        } catch (Exception e) {
            throw new OauthException("Github授权登录异常:" + e.getMessage());
        }
    }
}
